package org.truenewx.tnxjee.core.util.concurrent;

import org.springframework.beans.factory.DisposableBean;
import org.truenewx.tnxjee.core.util.LogUtil;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 默认线程池执行器
 *
 * @author jianglei
 */
public class DefaultThreadPoolExecutor extends ThreadPoolExecutor implements DisposableBean {

    private int logPerTaskCount = 10;

    // 核心线程数满了后，新任务进入等待队列，等待队列满了后才创建新线程执行，或等核心线程空闲后用核心线程执行等待的任务
    // 如果将queueCapacity设为0，则新任务不会进入等待队列，会立即创建新线程执行，在最大线程数满了后，会直接拒绝新任务，而不会等待执行
    public DefaultThreadPoolExecutor(int corePoolSize, int maxPoolSize, int queueCapacity) {
        super(corePoolSize, maxPoolSize, 60, TimeUnit.SECONDS,
                queueCapacity > 0 ? new LinkedBlockingQueue<>(queueCapacity) : new SynchronousQueue<>());
    }

    public DefaultThreadPoolExecutor(int corePoolSize, int maxPoolSize) {
        this(corePoolSize, maxPoolSize, maxPoolSize / 10);
    }

    public DefaultThreadPoolExecutor(int corePoolSize) {
        this(corePoolSize, corePoolSize * 100);
    }

    public void setLogPerTaskCount(int logPerTaskCount) {
        if (logPerTaskCount > 0) {
            this.logPerTaskCount = logPerTaskCount;
        }
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        long completedTaskCount = getCompletedTaskCount();
        if (completedTaskCount % this.logPerTaskCount == 0) {
            LogUtil.info(getClass(), "Thread pool:size={}, largest={}, active={}, completed={}",
                    getPoolSize(), getLargestPoolSize(), getActiveCount(), completedTaskCount);
        }
    }

    @Override
    public void destroy() throws Exception {
        shutdown();
    }

}
